package conMgr.ui;

import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.AbstractAction;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import conMgr.model.Conference;
import conMgr.model.Paper;
import conMgr.model.Review;
import conMgr.model.User;
import conMgr.model.UserType;
import conMgr.ui.papers.PaperView;
import conMgr.ui.util.ButtonBar;
import conMgr.ui.util.Ui;

/**
 * Represent specific conference information 
 * @author Soon Bang.
 *
 */
public class ConferenceView extends JPanel
{
	
	/**
	 * The serialization ID for this class.
	 */
	private static final long serialVersionUID = 1938404960529358926L;

	/**
	 * The date pattern.
	 */
	private static final String datePattern = "EEE, MM-dd-yyyy";
	
	/**
	 * The conference.
	 */
	private final Conference my_conference;

	/**
	 * The Current user.
	 */
	private final User my_user;
	
	/**
	 * The date formatter.
	 */
	private final SimpleDateFormat formatter;

	/**
	 * The conference information panel.
	 */
	private final JPanel my_conferenceInfoPanel;
	
	/**
	 * Represent table of papers.
	 */
	private final ConferencePaperView paperView;
	/**
	 * Today.
	 */
	private final Date today = new Date();
	
	/**
	 * The button bar for this panel.
	 */
	private final ButtonBar buttonBar;
	
	/**
	 * This class represent specific information of conference.
	 * Assigned ProgramChair can check recommendation from subprogram chair.
	 * Reviewers can see the all of submitting paper's lists.
	 * Authors can write new paper or edit their paper using paper title button.
	 * @param the_conf This current conference.
	 * @param the_user This current user.
	 */
	public ConferenceView(Conference the_conf, User the_user)
	{
		final GridBagLayout layout = new GridBagLayout();
		setLayout(layout);
		my_conference = the_conf;
		my_user = the_user;
		formatter = new SimpleDateFormat(datePattern);
		my_conferenceInfoPanel = new JPanel(new GridBagLayout());
		paperView = new ConferencePaperView(my_conference, my_user);
		

		GridBagConstraints constraints = new GridBagConstraints();
				
		constraints.insets = Ui.DEFAULT_INSETS;
		constraints.gridx = 0;
		constraints.gridy = 0;
		constraints.anchor = GridBagConstraints.WEST;
		add(makeConferenceInfo(), constraints);
		
		constraints = new GridBagConstraints();
		constraints.insets = Ui.DEFAULT_INSETS;
		constraints.gridx = 0;
		constraints.gridy = 1;
		constraints.anchor = GridBagConstraints.WEST;
		buttonBar = new ButtonBar();
		if (checkNewPaper())
			buttonBar.addButton("Create New Paper", new createNewPaperAction());
		if (checkViewPaper())
			buttonBar.addButton("View Paper", new ViewPaperAction());
		add(buttonBar, constraints);

		if(checkViewPaper())
		{
			constraints = new GridBagConstraints();
			constraints.insets = Ui.DEFAULT_INSETS;
			constraints.gridx = 0;
			constraints.gridy = 2;
			constraints.anchor = GridBagConstraints.WEST;
			add(paperView, constraints);
		}
		setVisible(true);
	}
	
	/**
	 * Checking the current user can write new paper.
	 * @return true If user can write new paper, return true otherwise false.
	 */
	public boolean checkNewPaper()
	{
		return
			User.getCurrentUser().getType() == UserType.AUTHOR &&
			today.before(my_conference.getSubmissionDL());
	}
	
	/**
	 * Checking the current user can see paper.
	 * @return true if user can see the paper otherwise false.
	 */
	public boolean checkViewPaper()
	{
		switch (User.getCurrentUser().getType())
		{
			case ADMIN:
				return true;
				
			case PROGRAM_CHAIR:
				if
				(
					my_conference.getProgramChair().equals(my_user) &&
					!my_conference.getPapers().isEmpty()
				)
					return true;
				break;
				
			case SUBPROGRAM_CHAIR:
				for(Paper paper : my_conference.getPapers())
					if (paper.getSubprogramChair() == User.getCurrentUser())
						return true;
				break;
				
			case AUTHOR:
				for (Paper paper : my_conference.getPapers())
					if (paper.getAuthor().equals(my_user))
						return true;
				break;
				
			case REVIEWER:
				for (Paper paper : my_conference.getPapers())
					for (Review review : paper.getPaperReviews())
						if (review.getReviewer().equals(my_user))
							return true;
				break;
		}
		
		return false;
	}
	/**
	 * Represent an action for paper view button.
	 * @author Soon Bang.
	 *
	 */
	class ViewPaperAction extends AbstractAction
	{

		/**
		 * The serialization ID for this class.
		 */
		private static final long serialVersionUID = -8224005495773044236L;

		/**
		 * Handle the create view paper action.
		 */
		@Override
		public void actionPerformed(ActionEvent e)
		{
			try
			{
				if(ConferencePaperView.getSelectedPaper() != null)
				{
					final PaperView pv = new PaperView(ConferencePaperView.getSelectedPaper(), my_conference);
					pv.setVisible(true);
				}
				else JOptionPane.showMessageDialog(null,"Select the paper",
	                    "Error",JOptionPane.ERROR_MESSAGE);
					
			}
			catch(Exception e1)
			{
				JOptionPane.showMessageDialog(null,"Select paper",
	                    "Error",JOptionPane.ERROR_MESSAGE);
			}
		}
	}
	/**
	 * Represent an action for create new paper button.
	 * @author Soon
	 *
	 */
	class createNewPaperAction extends AbstractAction
	{
		
		/**
		 * The serialization ID for this class.
		 */
		private static final long serialVersionUID = -2988810656261829758L;

		/**
		 * Handle the create new paper action, open null paper view.
		 */
		@Override
		public void actionPerformed(ActionEvent e)
		{
			try
			{
				final PaperView pv = new PaperView(null, my_conference);
				pv.setVisible(true);
			}
			catch(Exception e1)
			{
				JOptionPane.showMessageDialog(null, e1.getMessage());
			}
		}
	}

	/**
	 * Represent detail information of this conference.
	 * @return my_conferenceInfoPanel The main information of this conference.
	 */
	private JPanel makeConferenceInfo()
	{

		int col = 0;
		addGridBagFieldLabel("Submission DL: ", col++);
		addGridBagFieldLabel(formatter.format(my_conference.getSubmissionDL()), col++);
		addGridBagFieldLabel("Review Deadline", col++);
		addGridBagFieldLabel(formatter.format(my_conference.getReviewDL()), col++);
		addGridBagFieldLabel("Recommendation DL: ", col++);
		addGridBagFieldLabel(formatter.format(my_conference.getRecommendationDL()), col++);
		addGridBagFieldLabel("Revision DL: ", col++);
		addGridBagFieldLabel(formatter.format(my_conference.getRevisionDL()), col++);
		addGridBagFieldLabel("ProgramChair: ", col++);
		addGridBagFieldLabel(my_conference.getProgramChair().getName(), col++);
		final JLabel label = new JLabel(my_conference.getName());
		final Font f = new Font("", Font.PLAIN, 24);
		label.setFont(f);
		final GridBagConstraints constraints = new GridBagConstraints();
		constraints.gridx = 0;
		constraints.gridy = 0;
		constraints.gridwidth = col;
		constraints.anchor = GridBagConstraints.NORTHWEST;
		constraints.insets = Ui.DEFAULT_INSETS;
		my_conferenceInfoPanel.add(label, constraints);
		return my_conferenceInfoPanel;
	}

	/**
	 * Add the field of conference information.
	 * @param the_text The text of label.
	 * @param row The row of GridBagConstraints.
	 */
	private void addGridBagFieldLabel(final String the_text, final int col)
	{
		final JLabel label = new JLabel(the_text);
		final GridBagConstraints constraints = new GridBagConstraints();
		constraints.gridx = col;
		constraints.gridy = 1;
		constraints.anchor = GridBagConstraints.NORTHWEST;
		constraints.insets = Ui.DEFAULT_INSETS;
		my_conferenceInfoPanel.add(label, constraints);
		
	}
	
}
